import 'dart:math';

import 'package:flutter/material.dart';

class ImageHintWidget extends StatefulWidget {
  const ImageHintWidget(this.child);
  final Widget child;

  @override
  _ImageHintWidgetState createState() => _ImageHintWidgetState();
}

class _ImageHintWidgetState extends State<ImageHintWidget> {
  bool isHintShown = false;
  late Offset widgetPosition;
  late Offset initPosition;
  late Size widgetSize;
  late Size initSize;
  late double _endScale = 1.0;

  OverlayEntry? overlayEntry;
  late OverlayState overlayState;

  // 屏幕中触点个数
  int _pointers = 0;

  // final GlobalKey<ExtendedImageGestureState> gestureKey =
  //     GlobalKey<ExtendedImageGestureState>();

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
    closeHint();
  }

  void closeHint() {
    if (isHintShown) {
      overlayEntry?.remove();
      overlayEntry = null;
      setState(() {
        isHintShown = false;
      });
    }
  }

  void showHint() {
    findParent(this.context);
    overlayEntry = _overlayEntryBuilder();
    overlayState = Overlay.of(context);
    overlayState.insert(overlayEntry!);
    setState(() {
      isHintShown = true;
    });
  }

  findParent(BuildContext context) {
    RenderBox renderBox = context.findRenderObject() as RenderBox;
    widgetSize = renderBox.size;
    initSize = widgetSize;
    widgetPosition = renderBox.localToGlobal(Offset.zero);
    initPosition = widgetPosition;
  }

  OverlayEntry _overlayEntryBuilder() {
    return OverlayEntry(
      maintainState: true,
      builder: (context) {
        return GestureDetector(
          onTap: () {
            closeHint();
          },
          child: Container(
            height: MediaQuery.of(context).size.height,
            width: MediaQuery.of(context).size.width,
            color: Colors.black38,
            child: Stack(
              fit: StackFit.expand,
              children: [
                Positioned(
                  top: widgetPosition.dy,
                  left: widgetPosition.dx,
                  child: SizedBox(
                    width: widgetSize.width,
                    height: widgetSize.height,
                    child: widget.child,
                  ),
                ),
              ],
            ),
          ),
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Listener(
      onPointerDown: (event) => _pointers++,
      onPointerUp: (event) {
        _pointers--;
        if (_pointers == 0) {
          widgetSize = initSize;
          closeHint();
        }
      },
      onPointerSignal: (event) => {},
      child: GestureDetector(
        behavior: HitTestBehavior.opaque,
        onScaleStart: (details) {
          if (details.pointerCount == 2) {
            showHint();
          }
        },

        onScaleUpdate: (ScaleUpdateDetails details) {
          if (details.pointerCount == 1 && isHintShown) {
            double deltaDx = details.focalPointDelta.dx;
            double deltaDy = details.focalPointDelta.dy;
            if (_endScale > 1.6) {
              deltaDx *= 2.0;
              deltaDy *= 2.0;
            }
            overlayState.setState(() {
              widgetPosition = Offset(
                widgetPosition.dx + deltaDx,
                widgetPosition.dy + deltaDy,
              );
            });
          }
          if (details.pointerCount == 2 && isHintShown) {
            double imageScale = min(2.0, max(details.scale, 0.95));
            _endScale = imageScale;
            double deltaDx = details.focalPointDelta.dx * _endScale;
            double deltaDy = details.focalPointDelta.dy * _endScale;

            overlayState.setState(() {
              widgetSize = Size(
                initSize.width * imageScale,
                initSize.height * imageScale,
              );
              // widgetPosition = Offset(
              //   initPosition.dx - (widgetSize.width - initSize.width) / 2.0,
              //   initPosition.dy - (widgetSize.height - initSize.height) / 2.0,
              // );
              widgetPosition = Offset(
                widgetPosition.dx + deltaDx,
                widgetPosition.dy + deltaDy,
              );
            });
          }
        },
        // onScaleEnd: (ScaleEndDetails details) {
        //   if (details.pointerCount == 0) {
        //     print("最后一个手指离开屏幕");
        //   }
        // },
        child: IndexedStack(
          sizing: StackFit.expand,
          index: isHintShown ? 0 : 1,
          children: [
            SizedBox(),
            widget.child,
          ],
        ),
      ),
    );
  }
}
